package com.why.rpc.core.common.nacos;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;

import lombok.extern.slf4j.Slf4j;
import com.why.rpc.core.common.loadbalance.LoadBalancer;
import com.why.rpc.core.common.loadbalance.RoundRobinLoadBalancer;
import com.why.rpc.core.common.utils.NacosUtil;

import java.net.InetSocketAddress;
import java.util.List;

@Slf4j
public class DefaultNacosServiceRegistry implements ServiceRegistry {


    /**
     * 通过 NamingFactory 创建 NamingService 连接 Nacos，
     * 连接的过程写在了静态代码块中，在类加载时自动连接。
     * namingService 提供了两个很方便的接口，
     * registerInstance 和 getAllInstances 方法，前者可以直接向 Nacos 注册服务，
     * 后者可以获得提供某个服务的所有提供者的列表。所以接口的这两个方法只需要包装一下就好了。
     * <p>
     * 在 lookupService 方法中，通过 getAllInstance 获取到某个服务的所有提供者列表后，
     * 需要选择一个，这里就涉及了负载均衡策略，这里我们先选择第 0 个，后面某节会详细讲解负载均衡。
     */

    private LoadBalancer loadBalancer;

    public DefaultNacosServiceRegistry() {

    }

    public DefaultNacosServiceRegistry(LoadBalancer loadBalancer) {
        this.loadBalancer=loadBalancer;
    }


    @Override
    public void register(String serviceName, InetSocketAddress socketAddress) {


        try {
            log.info("使用工具类去注册中心注册服务");
            NacosUtil.registerService(serviceName, socketAddress);
        } catch (NacosException e) {
            log.error("注册服务的时候出现问题。。。");
            e.printStackTrace();
        }
    }

    @Override
    public InetSocketAddress getService(String serviceName) {
        loadBalancer = loadBalancer == null ? new RoundRobinLoadBalancer() : loadBalancer;
        try {
            List<Instance> allInstances = NacosUtil.getAllInstances(serviceName);
            Instance instance = loadBalancer.selectInstance(allInstances);

            log.info("获取服务:{}", instance.toString());
            return new InetSocketAddress(instance.getIp(), instance.getPort());
        } catch (NacosException e) {
            e.printStackTrace();
            log.info("获取服务失败！！！");
            throw new RuntimeException("注册中心获取服务出现错误");
        }

    }
}